package test;
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
import java.util.*;
/**
 * @Author: suncf
 * @Data: 2023年04月29日 9:05
 * @Version: V1.0
 * @Description:TODO
 */
public class LuckyNumbersGenerator {
    private static final int RED_BALL_COUNT = 33;
    private static final int BLUE_BALL_COUNT = 16;
    private static final int RED_BALL_COUNT_PER_TICKET = 6;
    private static final int BLUE_BALL_COUNT_PER_TICKET = 1;

    public static void main(String[] args) {
        List<List<Integer>> history = loadHistoryData("history.txt");
        BitSet redBallBitSet = new BitSet(RED_BALL_COUNT);
        BitSet blueBallBitSet = new BitSet(BLUE_BALL_COUNT);
        for (List<Integer> balls : history) {
            for (int i = 0, len = balls.size(); i < len - 1; i++) {
                int ball = balls.get(i) - 1;
                if (ball < RED_BALL_COUNT) {
                    redBallBitSet.set(ball);
                } else {
                    blueBallBitSet.set(ball - RED_BALL_COUNT);
                }
            }
        }
        int[] redBallFrequencyArray = calculateBallFrequency(redBallBitSet, RED_BALL_COUNT);
        int[] blueBallFrequencyArray = calculateBallFrequency(blueBallBitSet, BLUE_BALL_COUNT);
        List<Integer> luckyRedBalls = generateLuckyBalls(redBallFrequencyArray, RED_BALL_COUNT_PER_TICKET);
        List<Integer> luckyBlueBalls = generateLuckyBallsWithBlueOverlap(blueBallFrequencyArray, BLUE_BALL_COUNT_PER_TICKET, luckyRedBalls);
        System.out.println("幸运红球: " + luckyRedBalls);
        System.out.println("幸运蓝球: " + luckyBlueBalls);
    }

    private static List<List<Integer>> loadHistoryData(String fileName) {
        List<List<Integer>> history = new ArrayList<>();
        try (BufferedReader br = new BufferedReader(new FileReader(fileName))) {
            String line;
            while ((line = br.readLine()) != null) {
                String[] ballsStr = line.split("\\s+");
                List<Integer> balls = new ArrayList<>();
                for (int i = 0, len = ballsStr.length; i < len; i++) {
                    balls.add(Integer.parseInt(ballsStr[i]));
                }
                history.add(balls);
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
        return history;
    }

    private static int[] calculateBallFrequency(BitSet bitSet, int count) {
        int[] frequencyArray = new int[count];
        for (int i = 0; i < count; i++) {
            frequencyArray[i] = bitSet.get(i) ? 1 : 0;
        }
        return frequencyArray;
    }

    private static List<Integer> generateLuckyBalls(int[] frequencyArray, int count) {
        List<Integer> luckyBalls = new ArrayList<>();
        int[] indices = new int[count];
        // 从数组中选出频率最高的count个球
        for (int i = 0; i < count; i++) {
            int maxIndex = 0;
            int maxValue = 0;
            for (int j = 0, len = frequencyArray.length; j < len; j++) {
                if (frequencyArray[j] > maxValue && !luckyBalls.contains(j)) {
                    maxIndex = j;
                    maxValue = frequencyArray[j];
                }
            }
            indices[i] = maxIndex;
            luckyBalls.add(maxIndex);
        }
        // 对球号进行排序，以便于调试和显示
        Arrays.sort(indices);
        luckyBalls.clear();
        for (int i = 0; i < count; i++) {
            luckyBalls.add(indices[i] + 1);
        }
        return luckyBalls;
    }

    private static List<Integer> generateLuckyBallsWithBlueOverlap(int[] frequencyArray, int count, List<Integer> redBalls) {
        List<Integer> luckyBalls = new ArrayList<>();
        int maxIndex = 0;
        int maxValue = 0;
        Random random = new Random();
        // 取出redBalls中的一个作为蓝球
        int blueBallIndex = redBalls.get(random.nextInt(RED_BALL_COUNT_PER_TICKET));
        for (int i = 0; i < count; i++) {
            // 在剩余的ball中选出频率最高的ball
            for (int j = 0, len = frequencyArray.length; j < len; j++) {
                if (j != blueBallIndex && frequencyArray[j] > maxValue && !luckyBalls.contains(j)) {
                    maxIndex = j;
                    maxValue = frequencyArray[j];
                }
            }
            // 有概率将蓝球变成红球
            if (random.nextDouble() < 0.2 && i < count - 1) {
                luckyBalls.add(blueBallIndex + 1);
                blueBallIndex = maxIndex;
                maxValue = 0;
            } else {
                luckyBalls.add(maxIndex + 1);
                maxValue = 0;
            }
        }
        return luckyBalls;
    }
}
